/*************************************************************************
    > File Name    : TcpConnection.h
    > Author       : LiuLei
    > Mail         : 2261459486@qq.com 
    > Created Time : 2022年11月25日 星期五 11时15分13秒
 ************************************************************************/

#ifndef __LL_TCPCONNECTION_H__
#define __LL_TCPCONNECTION_H__

#include "Socket.h"
#include "SocketIO.h"
#include "InternetAddress.h"
#include <memory>
#include <functional>

using std::shared_ptr;
using std::function;

class EventLoop;
class TcpConnection;

using TcpConnectionPtr = shared_ptr<TcpConnection>;
using TcpConnectionCallback = function<void(const TcpConnectionPtr &ptr)>;

class TcpConnection
: public std::enable_shared_from_this<TcpConnection>
// 不继承这个类，不能够正确执行回调函数，可能存在智能指针的误用
{
public:
    TcpConnection(int peerfd, EventLoop *loop);
    ~TcpConnection();

    void sendMsg(const string &msg);
    void sendMsgInLoop(const string &msg);
    //EventLoop没有发送数据的能力，因此需要借助TcpConnection的sendMsg方法
    
    string recvMsg();
    
    string addrString();
    //打印网络信息

    bool isClosed() const;

    //EventLoop的回调函数注册
    void setConnectionCallback(const TcpConnectionCallback &cb);
    void setMessageCallback(const TcpConnectionCallback &cb);
    void setCloseCallback(const TcpConnectionCallback &cb);


    //如果为右值引用，那么EventLoop中只能使用一次，一旦使用std::move
    //值就转走了，下次就为空了                                      
    /* void setConnctionCallback(TcpConnectionCallback &&cb); */
    /* void setMessageCallback(TcpConnectionCallback &&cb); */
    /* void setCloseCallback(TcpConnectionCallback &&cb); */

    //EventLoop的回调函数执行
    void handleConnectionCallback();
    void handleMessageCallback();
    void handleCloseCallback();

private:
    //获取本端的网络信息                 
    InternetAddress getLocalAddr() const;
    //获取对端的网络信息                 
    InternetAddress getPeerAddr() const; 

private:
    EventLoop                   *_loop;
    Socket                      _socket;
    SocketIO                    _socketIO;
    InternetAddress             _localAddr;
    InternetAddress             _peerAddr;

    //回调函数
    TcpConnectionCallback       _onConnection;
    TcpConnectionCallback       _onMessage;
    TcpConnectionCallback       _onClose;
};

#endif
